#include <NTP.h>
#include <DateTime.h>
#include <ASocket.h>
#include <Client.h>
#include <Ethernet.h>
#include <Server.h>
#include <PString.h>
#include <Dhcp.h>
#include <Dns.h>
#include <string.h>
#include <WString.h>

//MAC ID\uff08\u5404\u30b7\u30fc\u30eb\u30c9\u306b\u8a18\u8f09\uff09
#include "WProgram.h"
void setup();
void loop();
void makeMsg(int post_count, int current, int ilum, int temp);
void post(char msg[]);
void getTime();
void printArray(Print *output, char* delimeter, byte* data, int len, int base);
void basic_make(const char *user_and_passwd);
static char mime_code(const char c);
void mimeEncode(const char *buf);
void alert();
byte mac[] = { 0x00, 0x50, 0xC2, 0x97, 0x23, 0x5E };

//ip\u304c\u901a\u3063\u305f\u304b
boolean ipAcquired = false;

//DNS\u30af\u30e9\u30b9
DnsClass targetDns;

//ip\u683c\u7d0d\u7528\u30d0\u30c3\u30d5\u30a1
byte buffer[6];

//NTP\u30b5\u30fc\u30d0\u306eip
byte ntp_dot_nist_dot_jp[] = {133, 243, 238, 243}; // ntp.nict.jp

//\u5404\u30bb\u30f3\u30b5\u30d4\u30f3
int ledPin =  2;
int CurrentPin = 0;
int IlumPin = 1;
int TempPin = 2;

//base64\u30a8\u30f3\u30b3\u30fc\u30c9\u5f8c\u306e\u6587\u5b57\u5217\u683c\u7d0d\u7528
char mime[65];

void setup()
{

  Serial.begin(9600);
  //\u5185\u90e8\u96fb\u5727\u8a2d\u5b9a
  analogReference( INTERNAL);
  pinMode(ledPin, OUTPUT); 
  
  ////////////////////////////////////
  /////\u30d9\u30fc\u30b7\u30c3\u30af\u8a8d\u8a3c\u7528ID\uff06PASS///////
  ////////////////////////////////////
  basic_make("tanikawa:tanikawa");
    
  Serial.println("getting ip...");
  int result = Dhcp.beginWithDHCP(mac);
  
  if(result == 1)
  {
    ipAcquired = true;
    
    Serial.println("ip acquired...");
    
    Dhcp.getMacAddress(buffer);
    Serial.print("mac address: ");
    printArray(&Serial, ":", buffer, 6, 16);
    
    Dhcp.getLocalIp(buffer);
    Serial.print("ip address: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    Dhcp.getSubnetMask(buffer);
    Serial.print("subnet mask: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    Dhcp.getGatewayIp(buffer);
    Serial.print("gateway ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    Dhcp.getDhcpServerIp(buffer);
    Serial.print("dhcp server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    Dhcp.getDnsServerIp(buffer);
    Serial.print("dns server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    
    //// Do DNS Lookup
    
    targetDns.init("100uhaco.appspot.com", buffer);  //Buffer contains the IP address of the DNS server
    targetDns.resolve();
   
    int results;
       
    while(!(results=targetDns.finished())) ;  //wait for DNS to resolve the name
    
    if(results != 1)
    {
      Serial.print("DNS Error code: ");
      Serial.print(results,DEC);
      alert();
    }
    
    
    targetDns.getIP(buffer);  //buffer now contains the IP address for google.com
    Serial.print("target IP address: ");
    printArray(&Serial, ".", buffer, 4, 10);
    
    //NTP\u540c\u671f
    NTP ntp(ntp_dot_nist_dot_jp);
    DateTime.sync( (ntp.get_unix_gmt() + (9 * 60 * 60)) );
        if( DateTime.available() ){
          Serial.println("NTP OK");
        }
        else{
          Serial.println("NTP FALSE");
          alert();
        }
  }
   else{
      Serial.println("unable to acquire ip address...");
      alert();
  }
}

void loop()
{
  digitalWrite(ledPin, LOW);
  //\u30dd\u30b9\u30c8\u6e08\u307f\u30ca\u30f3\u30d0\u30fc
  static int posted =0;
  static int SAMPLE_COUNT =0;
  static int max_current = 0;
  static int current_tmp = 0;
  static int ilum_sum = 0;
  static int temp_sum =0;
  //\u88dc\u6b63\u7528sec
  int sec;
   
  getTime();
  sec = (int)DateTime.Second; 
  
  //\u73fe\u5728\u306epnum\u3092\u751f\u6210
  int pnum = ((int)DateTime.Hour) * 6+ (int)DateTime.Minute / 10; 
    if(pnum >= 144){
       pnum = pnum - 144 ;
    }
  //10\u5206\u304a\u304d\u3001\u304b\u3064\u307e\u3060\u30dd\u30b9\u30c8\u3057\u3066\u3044\u306a\u304b\u3063\u305f\u5834\u5408
  if( ((int)DateTime.Minute % 10) == 0 && (pnum != posted)){
    int ilum_Value = 0;
    int temp_Value = 0;
    //\u5e73\u5747\u5316
    if(SAMPLE_COUNT != 0){
      ilum_Value = ilum_sum / SAMPLE_COUNT ;
      temp_Value = temp_sum / SAMPLE_COUNT ;
    }
    //HTTP\u901a\u4fe1 
    
    makeMsg(pnum, max_current, ilum_Value, temp_Value);
    
    
    //posted\u66f4\u65b0
    posted = pnum;
    
    //\u521d\u671f\u5316
    SAMPLE_COUNT =0;
    max_current = 0;
    current_tmp = 0;
    ilum_sum = 0;
    temp_sum =0;
    //\u70b9\u6ec5
    digitalWrite(ledPin,HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
  }
  //30\u79d2\u3054\u3068\u306b\u30c7\u30fc\u30bf\u3092\u53ce\u96c6
  else if( ( 0 == sec)|| (sec == 30) ){    
      //\u96fb\u529b\u30c7\u30fc\u30bf
      current_tmp = analogRead(CurrentPin);
        if(max_current < current_tmp){
          max_current = current_tmp;
        }
      //\u7167\u5ea6\u30c7\u30fc\u30bf
      ilum_sum +=analogRead(IlumPin);
      //\u6e29\u5ea6\u30c7\u30fc\u30bf
      temp_sum +=analogRead(TempPin);
      SAMPLE_COUNT++;
      Serial.println("logging");
      Serial.println(max_current);
      Serial.println(ilum_sum);
      Serial.println(temp_sum);
      
      delay(30000);
  }

}

//\u30e1\u30c3\u30bb\u30fc\u30b8\u4f5c\u6210\u51e6\u7406 
void makeMsg(int post_count, int current, int ilum, int temp)
{
  char msg[200];
  PString mystring(msg, sizeof(msg));
  
  mystring.print("GET http://100uhaco.appspot.com/haco/record/");
  mystring.print("?pnum=");
  mystring.print(post_count);
  mystring.print("&temp=");
  mystring.print(temp);
  mystring.print("&light=");
  mystring.print(ilum);
  mystring.print("&watt=");
  mystring.print(current); 
  mystring.println("  HTTP/1.0 ");
  mystring.print("Authorization: Basic ");
  mystring.println(mime);

  
  post(msg);
}


//GAE\u306b\u30dd\u30b9\u30c8
void post(char msg[])
{
   //
   //HTTP request phase
   //
   Client client(buffer,80);

   Serial.println("HTTP connecting...");
  
  if (client.connect()) {
    Serial.println("connected");
    //client.write(msg);
    client.println(msg);
    client.println();
    delay(100);
    Serial.println("disconnecting.");
    client.stop();
   }
}


void getTime(){
     if( DateTime.available() )
    {
       //\u306a\u305c\u304b\u4e00\u30f6\u6708\u9045\u308c\u306a\u306e\u3067\u66ab\u5b9a\u7684\u306b+1
       Serial.print((int)DateTime.Month + 1);
       Serial.print("/");
       Serial.print((int)DateTime.Day);       
       Serial.print(" ");
       Serial.print(((int)DateTime.Hour));
       Serial.print(":");
       Serial.print((int)DateTime.Minute);
       Serial.print(":");
       Serial.print((int)DateTime.Second);
       Serial.println(" JST"); 
    } 
}

//IPadress\u7fa4\u3092\u51fa\u529b\u3059\u308b\u305f\u3081\u306e\u51e6\u7406
void printArray(Print *output, char* delimeter, byte* data, int len, int base)
{
  char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

  for(int i = 0; i < len; i++)
  {
    if(i != 0)
      output->print(delimeter);

    output->print(itoa(data[i], buf, base));
  }

  output->println();
}

//
//\u30d9\u30fc\u30b7\u30c3\u30af\u8a8d\u8a3c\u7528base64\u30a8\u30f3\u30b3\u30fc\u30c9\u95a2\u6570\u90e1 
//(Twitter\u30e9\u30a4\u30d6\u30e9\u30ea\u304b\u3089\u62dd\u501f)
//

void basic_make(const char *user_and_passwd)
{
	mimeEncode(user_and_passwd);
}

static char mime_code(const char c)
{
	if (c < 26) return c+'A';
	if (c < 52) return c-26+'a';
	if (c < 62) return c-52+'0';
	if (c == 62) return '+';
	return '/';
}

void mimeEncode(const char *buf)
{
	int i = 0, j = 0, c[3];
	while (j < 64 && buf[i]) {
		c[0] = buf[i++];
		c[1] = buf[i] ? buf[i++] : 0;
		c[2] = buf[i] ? buf[i++] : 0;
		mime[j++] = mime_code(c[0]>>2);
		mime[j++] = mime_code(((c[0]<<4)&0x30) | (c[1]>>4));
		mime[j++] = c[1] ? mime_code(((c[1]<<2)&0x3c) | (c[2]>>6)) : '=';
		mime[j++] = c[2] ? mime_code(c[2]&0x3f) : '=';
	}
	mime[j] = 0;
}

void alert(){
  while(1){
       //\u30a2\u30e9\u30fc\u30c8
      digitalWrite(ledPin,HIGH);
      delay(500);
      digitalWrite(ledPin, LOW);
      delay(500);
  }
}



int main(void)
{
	init();

	setup();
    
	for (;;)
		loop();
        
	return 0;
}

